/*
 * FNISVGEditor - JavaScript - based editor for SVG graphics 
 * Copyright (C) 2008 - 2009 Antti Leppä / Foyt
 * http://www.foyt.fi
 * 
 * License: 
 * 
 * Licensed under GNU Lesser General Public License Version 2.1 or later (the "LGPL") 
 * http://www.gnu.org/licenses/lgpl.html
 */

FNISVGEditorLayersPlugin = Class.create(FNISVGEditorPlugin, {
  initialize : function($super, editorInstance, pluginURL) {
    $super(editorInstance, pluginURL);

    this._layerPanel = new FNIPanel();
    this._layerPanel.domNode.addClassName('fniSVGEditor_LayersPlugin_layerPanel');
    this._layerTools = new Element("div", {
      className : "fniSVGEditor_LayersPlugin_layerTools"
    });

    this._addLayerButton = new FNIPushButton( {});
    this._addLayerButton.domNode.addClassName('fniSVGEditor_LayersPlugin_addLayerButton');
    this._addLayerButton.setImage(this.getPluginURL() + "/gfx/icons/16x16/actions/document-new.png");
    this._addLayerButton.addListener("buttonClick", this, this._onAddLayerButtonClick);
    this._layerPanel.addGUIComponent(this._layerTools, this._addLayerButton);

    this._deleteLayerButton = new FNIPushButton( {});
    this._deleteLayerButton.domNode.addClassName('fniSVGEditor_LayersPlugin_deleteLayerButton');
    this._deleteLayerButton.addListener("buttonClick", this, this._onDeleteLayerButtonClick);
    this._deleteLayerButton.setImage(this.getPluginURL() + "/gfx/icons/16x16/actions/edit-delete.png");
    this._layerPanel.addGUIComponent(this._layerTools, this._deleteLayerButton);

    this._raiseLayerButton = new FNIPushButton( {});
    this._raiseLayerButton.domNode.addClassName('fniSVGEditor_LayersPlugin_raiseLayerButton');
    this._raiseLayerButton.addListener("buttonClick", this, this._onRaiseLayerButtonClick);
    this._raiseLayerButton.setImage(this.getPluginURL() + "/gfx/icons/16x16/actions/go-up.png");
    this._layerPanel.addGUIComponent(this._layerTools, this._raiseLayerButton);

    this._lowerLayerButton = new FNIPushButton( {});
    this._lowerLayerButton.domNode.addClassName('fniSVGEditor_LayersPlugin_lowerLayerButton');
    this._lowerLayerButton.addListener("buttonClick", this, this._onLowerLayerButtonClick);
    this._lowerLayerButton.setImage(this.getPluginURL() + "/gfx/icons/16x16/actions/go-down.png");
    this._layerPanel.addGUIComponent(this._layerTools, this._lowerLayerButton);
    this._layerList = new Element("div", {
      className : "fniSVGEditor_LayersPlugin_layerList"
    });
    this._layerPanel.domNode.appendChild(this._layerTools);
    this._layerPanel.domNode.appendChild(this._layerList);

    this.getEditorInstance().getEditorView().addGUIComponent(this._layerPanel);

    this._layerIds = 1;
    this._layers = new Hash();
    this._layerClickListener = this._onLayerClick.bindAsEventListener(this);
    this._layerVisibilityCheckBoxChangeListener = this._onLayerVisibilityCheckBoxChange.bindAsEventListener(this);

    this.getEditorInstance().getSVGDocument().addListener("layerCreated", this, this._onLayerCreated);
    this.getEditorInstance().getSVGDocument().addListener("layerRemoved", this, this._onLayerRemoved);
    this.getEditorInstance().getSVGDocument().addListener("currentLayerChanged", this, this._onCurrentLayerChanged);
    this.getEditorInstance().getSVGDocument().addListener("layerRaised", this, this._onLayerRaised);
    this.getEditorInstance().getSVGDocument().addListener("layerLowered", this, this._onLayerLowered);
    this.getEditorInstance().addListener("editorInitialized", this, this._onEditorInitialized);
  },
  getName : function() {
    return "layers";
  },
  _onEditorInitialized : function(event) {
    var layers = this.getEditorInstance().getSVGDocument().getLayers();
    for ( var i = 0; i < layers.length; i++) {
      this._addLayer(layers[i]);
    }
    this._updateButtonStates();
  },
  _addLayer : function(layer) {
    var titleElement = new Element("div", {
      className : "fniSVGEditor_LayersPlugin_layerTitle"
    });
    titleElement.innerHTML = layer.getAttribute("fnilayertitle");

    var visibleCB = new Element("input", {
      type : 'checkbox',
      className : "fniSVGEditor_LayersPlugin_visibleCheckbox",
      checked : true
    });
    
    var visibleContainer = new Element("div", {
      className : "fniSVGEditor_LayersPlugin_layerVisibleContainer"
    });
    visibleContainer.appendChild(visibleCB);
    var titleContainer = new Element("div", {
      className : "fniSVGEditor_LayersPlugin_layerTitleContainer"
    });
    titleContainer.appendChild(titleElement);

    var layerDiv = new Element("div", {
      className : "fniSVGEditor_LayersPlugin_layer"
    });
    
    layerDiv.appendChild(visibleContainer);
    layerDiv.appendChild(titleContainer);

    if (layer == this.getEditorInstance().getSVGDocument().getCurrentLayer())
      layerDiv.addClassName("fniSVGEditor_LayersPlugin_activeLayer");

    layerDiv._layer = layer;

    if (this._layerList.firstChild)
      this._layerList.insertBefore(layerDiv, this._layerList.firstChild);
    else
      this._layerList.appendChild(layerDiv);

    Event.observe(layerDiv, "click", this._layerClickListener);
    Event.observe(visibleCB, "change", this._layerVisibilityCheckBoxChangeListener);
  },
  _removeLayer : function(layer) {
    var elements = this._layerList.select(".fniSVGEditor_LayersPlugin_layer");
    for ( var i = 0; i < elements.length; i++) {
      if (elements[i]._layer == layer) {
        elements[i].remove();
        break;
      }
    }
  },
  _getNextLayerId : function() {
    return this._layerIds++;
  },
  _onLayerClick : function(event) {
    var layerElement = Event.element(event);
    if (!layerElement.hasClassName("fniSVGEditor_LayersPlugin_layer"))
      layerElement = layerElement.up(".fniSVGEditor_LayersPlugin_layer");

    this.getEditorInstance().getSVGDocument().setCurrentLayer(layerElement._layer);
  },
  _onLayerVisibilityCheckBoxChange : function(event) {
    var cbElement = Event.element(event);
    var layerElement = cbElement.up(".fniSVGEditor_LayersPlugin_layer");

    FNISVGEditorElementStylingUtils.setStyles(layerElement._layer, {
      'display' : cbElement.checked ? '' : 'none'
    });
  },
  _onCurrentLayerChanged : function(event) {
    var elements = this._layerList.select(".fniSVGEditor_LayersPlugin_layer");

    for ( var i = 0; i < elements.length; i++)
      elements[i].removeClassName("fniSVGEditor_LayersPlugin_activeLayer");

    var elements = this._layerList.select(".fniSVGEditor_LayersPlugin_layer");
    for ( var i = 0; i < elements.length; i++) {
      if (elements[i]._layer == event.layer) {
        elements[i].addClassName("fniSVGEditor_LayersPlugin_activeLayer");
        break;
      }
    }
    this._updateButtonStates();
  },
  _onLayerCreated : function(event) {
    this._updateButtonStates();
    this._addLayer(event.layer);
  },
  _onLayerRemoved : function(event) {
    this._updateButtonStates();
    this._removeLayer(event.layer);

  },
  _updateButtonStates : function() {
    var layers = this.getEditorInstance().getSVGDocument().getLayers();

    if (layers.length > 1) {
      var cLayer = this.getEditorInstance().getSVGDocument().getCurrentLayer();
      var index = -1;
      for ( var i = 0; i < layers.length; i++) {
        if (layers[i] == cLayer) {
          index = i;
          break;
        }
      }

      this._deleteLayerButton.setDisabled(false);
      this._raiseLayerButton.setDisabled(index > (layers.length - 2));
      this._lowerLayerButton.setDisabled(index < 1);
    } else {
      this._deleteLayerButton.setDisabled(true);
      this._raiseLayerButton.setDisabled(true);
      this._lowerLayerButton.setDisabled(true);
    }
  },
  _onAddLayerButtonClick : function(event) {
    var dialog = this.getEditorInstance().openDialog( {
      iconURL : this.getPluginURL() + '/gfx/icons/16x16/actions/document-new.png',
      title : SVGLocale.getText("layersPlugin_addNewLayerDialogTitle"),
      customCSS : this.getPluginURL() + '/dialog.css'
    });

    var _this = this;
    dialog.addListener("onLoad", function(event) {
      var errorMessageElement = new Element("div", {
        className : 'fniSVGEditor_LayersPlugin_newLayerDialog_errorMessage',
        style : 'display: none'
      });

      var titleInputElement = new Element("input", {
        className : 'fniSVGEditor_LayersPlugin_newLayerDialog_titleInput',
        type : 'text'
      });
      
      var titleTitleElement = new Element("div", { className : 'fniSVGEditor_LayersPlugin_newLayerDialog_titleTitle' }).update(SVGLocale.getText("layersPlugin_addNewLayerDialogLayerNameTitle")); 

      var titleElement = new Element("div", { className : 'fniSVGEditor_LayersPlugin_newLayerDialog_titleContainer' });
      titleElement.appendChild(titleTitleElement);
      titleElement.appendChild(titleInputElement);

      var okButton = new Element("button", {
        className : 'fniSVGEditor_LayersPlugin_newLayerDialog_okButton'
      }).update(SVGLocale.getText("layersPlugin_addNewLayerDialogOkButton"));

      Event.observe(okButton, "click", function() {
        var title = titleInputElement.value.strip();
        if (title == '') {
          errorMessageElement.innerHTML = SVGLocale.getText("layersPlugin_addNewLayerDialogLayerTitleIsMandatory");
          errorMessageElement.style.display = '';
          dialog.autoHeight();
        } else {
          var layer = _this.getEditorInstance().getSVGDocument().createLayer(title);
          _this.getEditorInstance().getSVGDocument().setCurrentLayer(layer);
          dialog.close();
        }
      });

      var cancelButton = new Element("button", {
        className : 'fniSVGEditor_LayersPlugin_newLayerDialog_cancelButton'
      }).update(SVGLocale.getText("layersPlugin_addNewLayerDialogCancelButton"));
      
      Event.observe(cancelButton, "click", function() {
        dialog.close();
      });

      var buttonsElement = new Element("div", {
        className : 'fniSVGEditor_LayersPlugin_newLayerDialog_buttonsContainer'
      });
      buttonsElement.appendChild(okButton);
      buttonsElement.appendChild(cancelButton);

      dialog.getContentElement().appendChild(errorMessageElement);
      dialog.getContentElement().appendChild(titleElement);
      dialog.getContentElement().appendChild(buttonsElement);

      dialog.setHeight(110);
      dialog.center();
      dialog.show();
    });
  },
  _onDeleteLayerButtonClick : function(event) {
    var dialog = this.getEditorInstance().openDialog( {
      iconURL : this.getPluginURL() + '/gfx/icons/16x16/status/dialog-warning.png',
      title : SVGLocale.getText("layersPlugin_confirmLayerDeleteDialogTitle"),
      customCSS : this.getPluginURL() + '/dialog.css'
    });
    
    var _this = this;
    dialog.addListener("onLoad", function(event) {
      var dialogText = new Element("div", { className : 'layersPlugin_confirmLayerDeleteDialogText' }).update(SVGLocale.getText("layersPlugin_confirmLayerDeleteDialogText"));  
      var textElement = new Element("div", { className : 'fniSVGEditor_LayersPlugin_deleteLayerDialog_textContainer' });
      textElement.appendChild(dialogText);
      var okButton = new Element("button", { className : 'fniSVGEditor_LayersPlugin_newLayerDialog_okButton' }).update(SVGLocale.getText("layersPlugin_confirmLayerDeleteDialogOkButton"));
      
      Event.observe(okButton, "click", function(event) {
        _this.getEditorInstance().getSelectionManager().clearElementSelection();
        var cLayer = _this.getEditorInstance().getSVGDocument().getCurrentLayer();
        var layers = _this.getEditorInstance().getSVGDocument().getLayers();
        for ( var i = 0; layers.length; i++) {
          if (layers[i] != cLayer) {
            _this.getEditorInstance().getSVGDocument().setCurrentLayer(layers[i]);
            break;
          }
        }

        _this._removeLayer(cLayer);
        _this.getEditorInstance().getSVGDocument().removeLayer(cLayer);

        dialog.close();
      });

      var cancelButton = new Element("button", { className : 'fniSVGEditor_LayersPlugin_removeLayerDialog_cancelButton' }).update(SVGLocale.getText("layersPlugin_confirmLayerDeleteDialogCancelButton"));
      Event.observe(cancelButton, "click", function() {
        dialog.close();
      });

      var buttonsElement = new Element("div", { className : 'fniSVGEditor_LayersPlugin_removeLayerDialog_buttonsContainer' });
      buttonsElement.appendChild(okButton);
      buttonsElement.appendChild(cancelButton);
      
      dialog.getContentElement().appendChild(textElement);
      dialog.getContentElement().appendChild(buttonsElement);

      dialog.setHeight(108);
      dialog.center();
      dialog.show();
    });
  },
  _onRaiseLayerButtonClick : function(event) {
    this.getEditorInstance().getSVGDocument().raiseLayer(this.getEditorInstance().getSVGDocument().getCurrentLayer());
  },
  _onLowerLayerButtonClick : function(event) {
    this.getEditorInstance().getSVGDocument().lowerLayer(this.getEditorInstance().getSVGDocument().getCurrentLayer());
  },
  _onLayerRaised : function(event) {
    var elements = this._layerList.select(".fniSVGEditor_LayersPlugin_layer");
    for ( var i = 1; i < elements.length; i++) {
      if (elements[i]._layer == event.layer) {
        elements[i].parentNode.insertBefore(elements[i], elements[i - 1]);
        break;
      }
    }
    this._updateButtonStates();
  },
  _onLayerLowered : function(event) {
    var elements = this._layerList.select(".fniSVGEditor_LayersPlugin_layer");
    for ( var i = 0; i < elements.length - 1; i++) {
      if (elements[i]._layer == event.layer) {
        elements[i].parentNode.insertBefore(elements[i], elements[i + 2]);
        break;
      }
    }
    this._updateButtonStates();
  }
});

document.fire("svgEditorPluginLoaded:layers", {
  pluginClass : FNISVGEditorLayersPlugin
});
